package com.kws.system.service.payment.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kws.common.core.domain.R;
import com.kws.common.core.utils.StringUtils;
import com.kws.system.domain.payment.TbAddressData;
import com.kws.system.domain.payment.info.QuerySignContractStatusInfo;
import com.kws.system.domain.payment.info.QuerySubBranchInfo;
import com.kws.system.domain.payment.info.UploadImageInfo;
import com.kws.system.domain.payment.rq.UploadContractFileRq;
import com.kws.system.mapper.payment.UnionPaySigningMapper;
import com.kws.system.service.payment.UnionPaySigningService;
import com.kws.system.util.HttpClientUtil;
import com.kws.system.util.ImgBase64Util;
import com.kws.system.util.ThreeDESUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * <b>UnionPaySigningServiceImpl</b>
 *
 * @description: UnionPaySigningServiceImpl <br>
 * @date: 2024/12/11 09:44 <br>
 * @author: lhm <br>
 * @version: 1.0 <br>
 */

@Service
public class UnionPaySigningServiceImpl extends ServiceImpl<UnionPaySigningMapper, TbAddressData> implements UnionPaySigningService {
    private static final Logger logger = LoggerFactory.getLogger(UnionPaySigningServiceImpl.class);


    @Value("${sign_contract.ACCESSER_ID}")
    public String ACCESSER_ID;

    @Value("${sign_contract.SECRET_KEY}")
    public String SECRET_KEY;

    @Value("${sign_contract.url}")
    public String url;

    @Override
    public List<TbAddressData> queryAddressDataByType(String type) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("type",type);
        List<TbAddressData> list = baseMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public R querySubBranch(String areaCode, String key) throws Exception {;
        JSONObject paramJson = new JSONObject();
        paramJson.put("service","branch_bank_list");
        paramJson.put("accesser_id",ACCESSER_ID);
        paramJson.put("sign_type","SHA-256");
        paramJson.put("request_date", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER));
        paramJson.put("request_seq", UUID.randomUUID().toString().replace("-",""));
        paramJson.put("areaCode",areaCode);
        paramJson.put("key",key);

        String jsonData = ThreeDESUtil.encode(JSONUtil.toJsonStr(paramJson), SECRET_KEY);
        String signData = ThreeDESUtil.getSign(JSONUtil.toJsonStr(paramJson));
        String resultObj = HttpClientUtil.doPost(url, ACCESSER_ID, jsonData, signData);
        logger.info("获取所属支行查询结果："+JSONUtil.parse(resultObj));
        if (StringUtils.isNotEmpty(resultObj)){
            JSONObject jsonObject = JSONObject.parseObject(resultObj);
            if (!"0000".equals(jsonObject.get("res_code"))){
                return R.fail(jsonObject.get("res_msg"));
            }
            List<QuerySubBranchInfo> branchBankList = JSONUtil.toList(JSONUtil.parseArray(jsonObject.get("branchBankList")), QuerySubBranchInfo.class);
            return R.ok(branchBankList);
        }else {
            return R.fail("查询所属支行失败!");
        }

    }

    @Override
    public R querySignContractStatus(String umsRegId) throws Exception {
        JSONObject paramJson = new JSONObject();
        paramJson.put("service","apply_qry");
        paramJson.put("accesser_id",ACCESSER_ID);
        paramJson.put("sign_type","SHA-256");
        paramJson.put("request_date", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER));
        paramJson.put("request_seq", UUID.randomUUID().toString().replace("-",""));
        paramJson.put("ums_reg_id",umsRegId);

        String jsonData = ThreeDESUtil.encode(JSONUtil.toJsonStr(paramJson), SECRET_KEY);
        String signData = ThreeDESUtil.getSign(JSONUtil.toJsonStr(paramJson));
        String resultObj = HttpClientUtil.doPost(url, ACCESSER_ID, jsonData, signData);
        logger.info("获取入网状态返回结果："+JSONUtil.parse(resultObj));
        if (StringUtils.isNotEmpty(resultObj)){
            QuerySignContractStatusInfo bean = JSONUtil.toBean(JSONUtil.parseObj(resultObj), QuerySignContractStatusInfo.class);
            if (!"0000".equals(bean.getRes_code())){
                return R.fail(bean.getRes_msg());
            }
            return R.ok(bean);
        }
        return null;
    }

    @Override
    public R createSignContract(String umsRegId,String channel) throws Exception {
        JSONObject paramJson = new JSONObject();
        paramJson.put("service","agreement_sign");
        paramJson.put("accesser_id",ACCESSER_ID);
        paramJson.put("sign_type","SHA-256");
        paramJson.put("request_date", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER));
        paramJson.put("request_seq", UUID.randomUUID().toString().replace("-",""));
        paramJson.put("ums_reg_id",umsRegId);
        paramJson.put("pcOrH5",channel);

        String jsonData = ThreeDESUtil.encode(JSONUtil.toJsonStr(paramJson), SECRET_KEY);
        String signData = ThreeDESUtil.getSign(JSONUtil.toJsonStr(paramJson));
        Map<String, String> param  = new HashMap<>();
        param.put("accesser_id", ACCESSER_ID);
        param.put("json_data", jsonData);
        param.put("sign_data", signData);
        String resultObj = HttpClientUtil.doGet(url, param);
        logger.info("发起前台签约返回结果："+JSONUtil.parse(resultObj));
        if (StringUtils.isNotEmpty(resultObj)){
            JSONObject jsonObject = JSONObject.parseObject(resultObj);
            if (!"0000".equals(jsonObject.get("res_code"))){
                return R.fail(jsonObject.get("res_msg"));
            }
            return R.ok();
        }
        return null;
    }

    @Override
    public R uploadSignContract(UploadContractFileRq rq) throws Exception {
        JSONObject paramJson = convertJsonData(rq);
        String jsonData = ThreeDESUtil.encode(JSONUtil.toJsonStr(paramJson), SECRET_KEY);
        String signData = ThreeDESUtil.getSign(JSONUtil.toJsonStr(paramJson));
        String resultObj = HttpClientUtil.doPost(url, ACCESSER_ID, jsonData, signData);
        logger.info("上传详细档案返回结果:{}"+resultObj);
        if (StringUtils.isNotEmpty(resultObj)){
            JSONObject jsonObject = JSONObject.parseObject(resultObj);
            if (!"0000".equals(jsonObject.get("res_code"))){
                return R.fail(jsonObject.get("res_msg"));
            }
            return R.fail(jsonObject);
        }
        return null;
    }

    public JSONObject convertJsonData(UploadContractFileRq rq){
        JSONObject json = new JSONObject();
        json.put("service","complex_upload");
        json.put("accesser_id",ACCESSER_ID);
        json.put("sign_type","SHA-256");
        json.put("request_date", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER));
        json.put("request_seq", UUID.randomUUID().toString().replace("-",""));
        json.put("accesser_user_id",rq.getMerchantId());
        json.put("reg_mer_type",rq.getRegMerType());
        json.put("legal_name",rq.getLegalName());
        json.put("legal_idcard_no",rq.getLegalIdcardNo());
        json.put("legal_mobile",rq.getLegalMobile());
        json.put("legalCardBeginDate",rq.getLegalCardBeginDate());
        json.put("legal_card_deadline",rq.getLegalCardDeadline());
        json.put("shop_name",rq.getShopName());
        json.put("bank_no",rq.getBankNo());
        json.put("bank_acct_type",rq.getBankAcctType());
        json.put("bank_acct_no",rq.getBankAcctNo());
        json.put("bank_acct_name",rq.getBankAcctName());
        json.put("shop_province_id",rq.getShopProvinceId());
        json.put("shop_city_id",rq.getShopCityId());
        json.put("shop_country_id",rq.getShopCountryId());
        json.put("shop_lic",rq.getShopLic());
        json.put("mccCode",rq.getMccCode());
        List<JSONObject> product = new ArrayList<>();
        JSONObject productJson = new JSONObject();
        productJson.put("product_id","in1");
        productJson.put("receipt2Line","0");
        JSONObject productJson1 = new JSONObject();
        productJson1.put("product_id","in2");
        productJson1.put("receipt2Line","0");
        JSONObject productJson2 = new JSONObject();
        productJson2.put("product_id","in3");
        productJson2.put("receipt2Line","0");
        JSONObject productJson3 = new JSONObject();
        productJson3.put("product_id","in4");
        productJson3.put("receipt2Line","0");
        JSONObject productJson4 = new JSONObject();
        productJson4.put("product_id","in8");
        productJson4.put("receipt2Line","0");
        product.add(productJson);
        product.add(productJson1);
        product.add(productJson2);
        product.add(productJson3);
        product.add(productJson4);
        json.put("product",product);
        json.put("shareholderName",rq.getShareholderName());
        json.put("shareholderCertno",rq.getShareholderCertno());
        json.put("shareholderCertBeginDate",rq.getShareholderCertBeginDate());
        json.put("shareholderCertExpire",rq.getShareholderCertExpire());
        json.put("shareholderCertType",rq.getShareholderCertType());
        json.put("shareholderHomeAddr",rq.getShareholderHomeAddr());
        if (CollectionUtil.isNotEmpty(rq.getBnfList())){
            List<JSONObject> entries = new ArrayList<>();
            rq.getBnfList().forEach(item -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("bnfName",item.getBnfName());
                jsonObject.put("bnfCertno",item.getBnfCertno());
                jsonObject.put("bnfCertBeginDate",item.getBnfCertBeginDate());
                jsonObject.put("bnfCertExpire",item.getBnfCertExpire());
                jsonObject.put("bnfCertType",item.getBnfCertType());
                jsonObject.put("bnfHomeAddr",item.getBnfHomeAddr());
                entries.add(jsonObject);
            });
            json.put("bnfList",entries);
        }
        json.put("legalmanHomeAddr",rq.getLegalmanHomeAddr());
        List<JSONObject> picList = new ArrayList<>();
        rq.getPicList().forEach(item -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("document_type",item.getDocumentType());
            jsonObject.put("document_name",item.getDocumentName());
            jsonObject.put("file_path",item.getFilePath());
            jsonObject.put("file_size",item.getFileSize());
            picList.add(jsonObject);
        });
        json.put("pic_list",picList);
        json.put("isChain",rq.getIsChain());
        return json;
    }

    @Override
    public R uploadFile(MultipartFile file) throws Exception {
        JSONObject paramJson = new JSONObject();
        paramJson.put("service","pic_upload");
        paramJson.put("accesser_id",ACCESSER_ID);
        paramJson.put("sign_type","SHA-256");
        paramJson.put("request_date", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER));
        paramJson.put("request_seq", UUID.randomUUID().toString().replace("-",""));
        paramJson.put("pic_base64",convertImageToBase64(file));

        String jsonData = ThreeDESUtil.encode(JSONUtil.toJsonStr(paramJson), SECRET_KEY);
        String signData = ThreeDESUtil.getSign(JSONUtil.toJsonStr(paramJson));
        String resultObj = HttpClientUtil.doPost(url, ACCESSER_ID, jsonData, signData);
        logger.info("上传图片返回结果："+JSONUtil.parse(resultObj));
        if (StringUtils.isNotEmpty(resultObj)){
            UploadImageInfo info = JSONUtil.toBean(resultObj, UploadImageInfo.class);
            if (!"0000".equals(info.getRes_code())){
                return R.fail(info.getRes_msg());
            }
            return R.ok(info);
        }
        return null;
    }


    public static String convertImageToBase64(MultipartFile file) throws IOException {
        byte[] fileBytes = file.getBytes();
        String base64String = Base64.getEncoder().encodeToString(fileBytes);
        // 添加前缀"data"
        String dataPrefix = "data:image/png;base64,"; // 根据实际图片类型选择image/png或其他
        return dataPrefix + base64String;
    }
}
